123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- "use client";
- import {
- getRank,
- getRankDetail,
- Rank,
- RankDetail,
- RankItem,
- RankRequestParams,
- RankReward,
- } from "@/api/activity";
- import { userInfoApi } from "@/api/login";
- import CustomButton from "@/components/CustomButton";
- import HeaderBack from "@/components/HeaderBack";
- import Tabs from "@/components/Tabs";
- import { HeaderImageMap, RankSourceMap } from "@/enums";
- import { useRouter } from "@/i18n/routing";
- import { cryptoStr } from "@/utils";
- import { useRequest } from "ahooks";
- import { InfiniteScroll } from "antd-mobile";
- import clsx from "clsx";
- import Image from "next/image";
- import React from "react";
- import styles from "./page.module.scss";
- const Page = () => {
- const { data: userInfo, run: refreshUserInfo } = useRequest<any, any>(userInfoApi, {
- pollingErrorRetryCount: 1,
- });
- const router = useRouter();
- const [initLoading, setInitLoading] = React.useState<boolean>(true);
- const [areaId, setAreaId] = React.useState<number>(1);
- const [loading, setLoading] = React.useState<boolean>(false);
- const [data, setData] = React.useState<RankDetail>({} as RankDetail);
- const [noMore, setNoMore] = React.useState<boolean>(false);
- const [rankList, setRankList] = React.useState<Rank[]>([]);
- const [rankData, setRankData] = React.useState<RankItem[]>([]);
- const [currentSource, setCurrentSource] = React.useState<any>({
- source: 1,
- type: 1,
- });
- // source 来源(1现金投注2现金+彩金投注3免费币投注4重玩币投注5现金充值6邀请玩家)
- // type 榜单类型(0小时榜1日榜单2周榜单3月榜)
- const pageInfo = React.useRef({
- page: 0,
- });
- const SourceObject = React.useMemo(() => {
- if (!rankData?.length) return [];
- const source: any = {};
- rankData?.forEach((item) => {
- if (!source[item.source]) {
- source[item.source] = {};
- }
- source[item.source][item.type] = item;
- });
- return source;
- }, [rankData]);
- const Tab1Cfg = React.useMemo(() => {
- if (!SourceObject) return [];
- const result: any = [];
- Object.keys(SourceObject).forEach((key) => {
- const curSource = RankSourceMap.get(Number(key)) || ({} as any);
- result.push({
- id: key,
- name: (
- <div className="flex items-center justify-center">
- <img
- className="pic needsclick relative z-[-1] w-[46px]"
- src={curSource?.img}
- alt=""
- />
- <div className="needsclick relative w-[80px] whitespace-normal break-all text-center text-[12px] font-black leading-[1]">
- {curSource.text}
- </div>
- </div>
- ),
- });
- });
- return result;
- }, [SourceObject]);
- const Tab2Cfg = React.useMemo(() => {
- if (!SourceObject[currentSource.source]) return [];
- const result: any = [];
- Object.keys(SourceObject[currentSource.source]).forEach((key) => {
- const curType = RankSourceMap.get(Number(key)) || ({} as any);
- result.push({
- id: key,
- name: (
- <div className="flex flex-col items-center justify-center">
- <div className="text-[14px] font-black leading-[1]">DIA</div>
- <div className="flex flex-row items-center justify-center gap-[5px] text-[12px] text-[var(--primary-button)]">
- <i className="iconfont icon-daojishi-hui !text-[13px]"></i>
- <div className="countdownTimer needsclick flex flex-row items-center justify-center gap-[1px]">
- <span>01</span>:<span>01</span>:<span>01</span>
- </div>
- </div>
- </div>
- ),
- });
- });
- return result;
- }, [SourceObject, currentSource]);
- const getRankData = async () => {
- const res = await getRank();
- if (res.code === 200) {
- setRankData(res?.data || []);
- }
- };
- React.useEffect(() => {
- getRankData();
- }, []);
- React.useEffect(() => {
- pageInfo.current.page = 0;
- setRankList([]);
- setData({} as any);
- // getData(areaId);
- }, [areaId]);
- const getData = async (id: number) => {
- if (loading) return;
- try {
- setLoading(true);
- if (pageInfo.current?.page === 1) {
- setInitLoading(true);
- }
- const params: RankRequestParams = {
- area_id: id,
- type: 0,
- page: pageInfo.current?.page || 1,
- };
- const res = await getRankDetail(params);
- if (res?.code === 200) {
- setData(res.data);
- if (!res?.data?.list || (res?.data?.list && res?.data?.list?.length < 10)) {
- setNoMore(true);
- }
- setRankList((value) => {
- return [...(value || []), ...(res?.data?.list || [])];
- });
- }
- } finally {
- setLoading(false);
- setInitLoading(false);
- }
- };
- const getNumber = (num: number) => {
- if (num > 3) return num;
- return <img className="inline-block w-[.18rem]" src={`/rank/f${num}.webp`} alt=""></img>;
- };
- const sourceChange = (actKey: any, key: any) => {
- setCurrentSource((state: any) => ({ ...state, [key]: actKey }));
- };
- return (
- <div className={styles.page}>
- <HeaderBack
- showBack={true}
- title={
- <div className="flex items-center justify-center">
- <i className="iconfont icon-jiangbei mr-[.1rem] text-[.22rem] text-[var(--textColor4)]"></i>
- <span className="leading-[1]">Ranking</span>
- </div>
- }
- />
- <main className={"main-header hasFlag stickyFlag"} id="mainBox">
- <div className="h-[100%] p-[.1rem]">
- <div className={styles.pageContainer}>
- <div className={styles.tabTop}>
- <Tabs
- items={Tab1Cfg}
- activeKey={currentSource.source}
- onChanage={(val) => sourceChange(val, "source")}
- ></Tabs>
- </div>
- <div className={styles.tabType}>
- <Tabs items={Tab2Cfg}></Tabs>
- </div>
- <div className="min-h-[0] flex-1 overflow-auto">
- <div
- className={clsx(
- styles.total,
- "flex w-full flex-row items-stretch gap-[15px] rounded-[var(--borderRadius)] p-[15px]"
- )}
- >
- <img
- src="/rank/H7_jackpot_jiangbei_icon.webp"
- alt=""
- className="w-[100px]"
- />
- <div className="flex flex-1 flex-col justify-between leading-[1]">
- <div className="flex items-center">
- <img
- className="w-[10px]"
- src="/rank/H7_jackpot_yezi_icon.webp"
- style={{
- transform: "rotateY(180deg)",
- transformOrigin: "center",
- }}
- alt=""
- />
- <span className="mx-[.1rem] text-[14px] font-black">
- Daily Contest
- </span>
- <img
- className="w-[10px]"
- src="/rank/H7_jackpot_yezi_icon.webp"
- alt=""
- />
- </div>
- <div className="text text-[14px]">Contest prize pool</div>
- <div
- style={{
- boxShadow: "0 0 0 1px var(--primary-button) inset",
- }}
- className="flex items-center rounded-[var(--borderRadius)] bg-[#fff] py-[6px] pl-[20px] text-[17px] font-black tracking-[2px] text-[var(--textColor4)]"
- >
- R$ {data?.total || 0}
- </div>
- <div className="text-[12px]">
- 2025-07-30 00:00 ~ 2025-07-31 00:00
- </div>
- </div>
- </div>
- <div className="mt-[.1rem] rounded-[var(--borderRadius)] bg-[var(--main-background)] px-[15px] py-[10px]">
- <div className="flex items-center justify-between border-b-[1px] border-[var(--primary-button)] pb-[.1rem]">
- <Image
- src={HeaderImageMap.get(1)?.img || "/img/avatar.webp"}
- className={"mr-[.1rem] h-[58px] w-[58px] rounded-[50%]"}
- alt={"avatar"}
- width={120}
- height={120}
- />
- <div className="flex flex-1 flex-col justify-between">
- <div className="font-black">
- {cryptoStr(data?.self_rank?.nickName)}
- </div>
- <div>Apostas: 0</div>
- </div>
- <CustomButton className="!px-[.1rem] !py-[.08rem]">
- Aposte
- </CustomButton>
- </div>
- <div className="mt-[10px] flex items-center">
- <div className="flex flex-1 flex-col items-center justify-between border-r-[1px] border-[var(--primary-button)]">
- <div className="text-[14px] font-black">Meu ranking</div>
- <div className="mt-[8px] text-[16px] font-black">
- Fora do ranking
- </div>
- </div>
- <div className="flex flex-1 flex-col items-center justify-between">
- <div className="text-[14px] font-black">Prêmio</div>
- <div className="mt-[8px] text-[14px] font-black">
- {data?.self_rank?.reward && data.self_rank.reward[0]
- ? data.self_rank.reward[0].amount
- : 0}{" "}
- <span className="text-[var(--textColor4)]">
- (
- {data?.self_rank?.reward && data.self_rank.reward[0]
- ? data.self_rank.reward[0].ratio
- : 0}
- %)
- </span>
- </div>
- </div>
- </div>
- </div>
- <h3 className="py-[.1rem] text-center text-[14px] text-[var(--textColor2)]">
- Aposte para subir no ranking
- </h3>
- <div className="mt-[.1rem] flex items-center justify-between">
- <CustomButton
- className={styles.agentBtn}
- onClick={() => router.push("/rank/history")}
- >
- <i className="iconfont icon-huodejiangli mr-[.1rem] scale-[1.4] transform text-[var(--primary-button)]"></i>
- <span className="text-[var(--textColor1)]">
- Prêmio histórico
- </span>
- </CustomButton>
- <CustomButton
- className={styles.agentBtn}
- onClick={() => router.push("/rank/rules")}
- >
- <i className="iconfont icon-wenjian mr-[.1rem] scale-[1.4] transform text-[var(--primary-button)]"></i>
- <span className="text-[var(--textColor1)]">Regras</span>
- </CustomButton>
- </div>
- <div>
- <div className="flex items-center px-[10px] py-[10px] text-[.13rem] font-black">
- <div className="w-[40px] text-center">Rank</div>
- <div className="w-[100px] text-center">Jogador</div>
- <div className="w-[80px] text-center">Apostas</div>
- <div className="flex-1 text-right">Prêmio</div>
- </div>
- {!!rankList?.length &&
- rankList.map((item) => {
- let curReward: RankReward = {} as RankReward;
- if (item?.reward?.length) {
- curReward = item?.reward[0];
- }
- return (
- <div
- key={item.rank}
- className="flex items-center px-[10px] py-[10px] text-[.12rem] font-normal"
- >
- <div className="w-[40px] text-center">
- {getNumber(item.rank)}
- </div>
- <div className="w-[100px] text-center">
- {cryptoStr(item?.nickName)}
- </div>
- <div className="w-[80px] text-center text-[var(--textColor4)]">
- {item.score}
- </div>
- <div className="flex-1 text-right text-[var(--textColor4)]">
- R${curReward?.amount || 0}
- <span className="text-[var(--textColor1)]">
- ({curReward?.ratio || 0}%)
- </span>
- </div>
- </div>
- );
- })}
- <InfiniteScroll
- hasMore={!noMore}
- loadMore={async () => {
- pageInfo.current.page++;
- await getData(areaId);
- }}
- ></InfiniteScroll>
- </div>
- </div>
- </div>
- </div>
- </main>
- </div>
- );
- };
- export default Page;
|